﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IndignadoFramework.BackBone.Model;
using IndignadoFramework.DataAccessLayer.EntityModels;
using System.Data.Entity;
using System.Data.Objects;
using System.Net;
using System.Net.Mail;
using System.Globalization;




namespace IndignadoFramework.BackBone.InternalServices.Implementacion
{
    public class ConvocatoriaServicesImpl : ConvocatoriaServices
    {
        public int addConvocatoria(ConvocatoriaModel conv)
        {
            Convocatoria convocatoriaEntity = new Convocatoria();
            AutoMapper.Mapper.CreateMap<ConvocatoriaModel, Convocatoria>();
            convocatoriaEntity = AutoMapper.Mapper.Map(conv, convocatoriaEntity);
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities()) {
                context.AddObject("Convocatorias", convocatoriaEntity);
                context.SaveChanges();
            }
            return convocatoriaEntity.Id;
        }

        public IEnumerable<ConvocatoriaModel> listarConvocatorias(int movimientoId)
        {
            List<ConvocatoriaModel> listaConvocatorias = new List<ConvocatoriaModel>();
            IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
            DateTime now = System.DateTime.Now;
            IQueryable<Convocatoria> convocatorias = 
                from conv in context.Convocatorias 
                where conv.MovimientoId==movimientoId && conv.ConvocatoriaFechaFin >= now select conv;
            foreach (Convocatoria convocatoriaEntity in convocatorias) {
                ConvocatoriaModel convocatoriaModel = new ConvocatoriaModel();
                AutoMapper.Mapper.CreateMap<Convocatoria, ConvocatoriaModel>();
                convocatoriaModel = AutoMapper.Mapper.Map(convocatoriaEntity, convocatoriaModel);
                convocatoriaModel.CategoriaTematicaNombre = convocatoriaEntity.CategoriaTematica.CategoriaTematicaNombre;
                if ((convocatoriaEntity.ConvocatoriaFechaInicio - now).Days < 1
                        && convocatoriaEntity.Usuario.Count < convocatoriaEntity.ConvocatoriaQuorum)
                {
                    convocatoriaModel.ConvocatoriaEstado = ConvocatoriaModel.EstadoConvocatoria.Suspendida;
                }
                else
                {
                    if (convocatoriaEntity.ConvocatoriaFechaInicio <= now)
                    {
                        convocatoriaModel.ConvocatoriaEstado = ConvocatoriaModel.EstadoConvocatoria.Desarrollandose;
                    }
                    else
                    {
                        convocatoriaModel.ConvocatoriaEstado = ConvocatoriaModel.EstadoConvocatoria.ARealizarse;
                    }
                }
                listaConvocatorias.Add(convocatoriaModel);
            }
            return listaConvocatorias.OrderBy(lista => lista.ConvocatoriaFechaInicio);
        }

        public List<ConvocatoriaModel> listarTodasConvocatoriasPhone()
        {
            List<ConvocatoriaModel> listaConvocatorias = new List<ConvocatoriaModel>();
            
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                //context.Connection.Open();
               //// IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
                DateTime now = System.DateTime.Now;
                IQueryable<Convocatoria> convocatorias =
                    from conv in context.Convocatorias
                    where conv.ConvocatoriaFechaFin >= now
                    select conv;
                //ConvocatoriaModel ca = new ConvocatoriaModel();
                //ca.ConvocatoriaTitulo = "as1sdsYEAH";
                foreach (var c in convocatorias)
                {
                    //ca.ConvocatoriaTitulo = ca.ConvocatoriaTitulo + "1";
                    ConvocatoriaModel convocatoriaModel = new ConvocatoriaModel();
                    convocatoriaModel.ConvocatoriaTitulo = c.ConvocatoriaTitulo;
                    convocatoriaModel.Id = c.Id;
                    //AutoMapper.Mapper.CreateMap<Convocatoria, ConvocatoriaModel>();
                    //convocatoriaModel = AutoMapper.Mapper.Map(c, convocatoriaModel);
                    listaConvocatorias.Add(convocatoriaModel);
                    Console.WriteLine("agregada la convocatoria" + c.ConvocatoriaTitulo);
                }


                //ca.Id = 1;
                //listaConvocatorias.Add(ca);

                //ConvocatoriaModel ca2 = new ConvocatoriaModel();
                //ca2.ConvocatoriaTitulo = "as2";
                //ca2.Id = 2;
                //listaConvocatorias.Add(ca2);
            }
            return listaConvocatorias;
        }


        public ConvocatoriaModel getConvocatoria(int convocatoriaId) {
            IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
            IQueryable<Convocatoria> query = from conv in context.Convocatorias
                               where conv.Id == convocatoriaId
                               select conv;
            Convocatoria convocatoriaResult = query.First();
            ConvocatoriaModel convocatoriaModel = new ConvocatoriaModel();
            AutoMapper.Mapper.CreateMap<Convocatoria, ConvocatoriaModel>();
            convocatoriaModel = AutoMapper.Mapper.Map(convocatoriaResult, convocatoriaModel);
            convocatoriaModel.CategoriaTematicaNombre = convocatoriaResult.CategoriaTematica.CategoriaTematicaNombre;
            return (convocatoriaModel);

        }


        public byte[] getConvocatoriaLogo(int movimientoId, int convocatoriaId)
        {
            IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
            //Busco el movimiento
            Convocatoria convocatoria = (from conv in context.Convocatorias
                                         where conv.Id == convocatoriaId && conv.MovimientoId == movimientoId
                                         select conv).SingleOrDefault();
            return convocatoria.ConvocatoriaLogo;
        }

        // usuarioId es el que creo la convocatoria 
        public void notificarUsuario(int usuarioId, int convocatoriaId, string mailSubject, string mailBody)
        {
            IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
            Convocatoria convocatoria = (from conv in context.Convocatorias where conv.Id == convocatoriaId select conv).SingleOrDefault();
            string ConvocatoriaUbicacionX = convocatoria.ConvocatoriaUbicacionX;
            string ConvocatoriaUbicacionY = convocatoria.ConvocatoriaUbicacionY;
            Usuario usuarioCreador = (from usr in context.Usuarios where usr.Id == usuarioId select usr).SingleOrDefault();
            IQueryable<Usuario> usuarios = from usr in context.Usuarios
                                           where usr.MovimientoId == usuarioCreador.MovimientoId //pertenece al movimiento
                                             &&  usr.Id != usuarioCreador.Id // no es el usuairo creador de la convocatoria
                                           select usr;
            // luego que obtengo los usuarios mando los mails
            foreach(Usuario usuario in usuarios){
                // esta a menos de 50 km o tiene una categoria tematica del movimiento
                if (radio50kM(ConvocatoriaUbicacionX, ConvocatoriaUbicacionY, usuario.UsuarioUbicacionX, usuario.UsuarioUbicacionY) == true)
                {
                    string mail = usuario.UsuarioMail;
                    enviarMail(mail, mailSubject, mailBody);
                }
                else
                {
                    if (UsuarioTieneCategoriaTematicaConvocatoria(usuario.Id, convocatoria.Id) == true)
                    {
                        string mail = usuario.UsuarioMail;
                        enviarMail(mail, mailSubject, mailBody);
                    }

                } 
                                                  
                
            }
        }

        public double GetEuclideanDistance(double x1, double y1, double x2, double y2)
        {
            return Math.Sqrt(Math.Pow((x1 - x2), 2) + Math.Pow((y1 - y2), 2));
        }

        public bool radio50kM(string centroX, string centroY, string puntoX, string puntoY)
        {
            double CentroX = double.Parse(centroX, CultureInfo.InvariantCulture);
            double CentroY = double.Parse(centroY, CultureInfo.InvariantCulture);
            double PuntoX = double.Parse(puntoX, CultureInfo.InvariantCulture);
            double PuntoY = double.Parse(puntoY, CultureInfo.InvariantCulture);
           
            double distancia = GetEuclideanDistance(CentroX,CentroY,PuntoX,PuntoY);
             // chequear que el * 100 esta bien
            return ((distancia * 100) <= 50);
        }

        public bool UsuarioTieneCategoriaTematicaConvocatoria(int usuarioId, int convocatoriaId)
        {
            IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
            Usuario usuario = (from usr in context.Usuarios
                                           where usr.Id == usuarioId
                                           select usr).SingleOrDefault();
            Convocatoria convocatoria = (from conv in context.Convocatorias
                                          where conv.Id == convocatoriaId
                                          select conv).SingleOrDefault();
            bool retorno = false;
            foreach (CategoriaTematica categoriaUsuario in usuario.CategoriaTematica)
            {
                if (categoriaUsuario.Id == convocatoria.CategoriaTematica.Id)
                {
                    retorno = true;
                    break;
                }
            }
            return retorno;
        }

        public bool enviarMail(string mail, string subjetc, string body)
        {
            try
            {
                //Mail Message
                MailMessage mM = new MailMessage();
                //Mail Address
                mM.From = new MailAddress("indignadoframework@hotmail.com");
                //receiver email id
                mM.To.Add(mail);
                //subject of the email
                mM.Subject = subjetc;
                //deciding for the attachment
                //mM.Attachments.Add(new Attachment(@"C:\\attachedfile.jpg"));
                //add the body of the email
                mM.Body = body;
                mM.IsBodyHtml = true;
                //SMTP client
                SmtpClient sC = new SmtpClient("smtp.live.com");
                //port number for Hot mail
                sC.Port = 25;
                //credentials to login in to hotmail account
                sC.Credentials = new NetworkCredential("indignadoframework@hotmail.com", "Empanadas");
                //enabled SSL
                sC.EnableSsl = true;
                //Send an email
                sC.Send(mM);
                return true;
            }//end of try block
            catch (Exception)
            {
                return false;
            }
        }
    }
}
